<?php

/**
 * Fonctionnement du moteur de recherche
 */
class Search
{
    // Attributs
    const cached = true;
    const cache_folder = 'cache/search/';
    const cache_delay = 2592000; // 1 mois
    private $_cache;
    
    /**
     * Constructeur
     */
    public function __construct()
    {
    }

    /**
     * Récupère les données pour le champ de recherche
     *
     * @param string $query La valeur actuelle du champ
     * @param array $types Le type de données à retrouver
     * @param bool $json Effectue une recherche dans les fichiers JSON
     * @return mixed $data Toutes les occurences contenant la valeur du champ
     */
    public function MySearch($query, array $types, $json = false)
    {
        $data = array();

        $file_cache = self::cache_folder.md5($query.implode('',$types)).'.json';
        $filemtime = getlastmod ($file_cache);
        $file_delay_rest = time() - $filemtime;

        /* Supprime le fichier si trop vieux */
        if (file_exists($file_cache) && $file_delay_rest > self::cache_delay) {
            FB('unset file');
            unlink($file_cache);
        }

        if(file_exists($file_cache) && self::cached){
            FB('load from cache');
            return file_get_contents($file_cache);
        } else {
            FB('no cache file');
            $this->_cache = (object)array();
        }

        FB('Search in method');
        foreach ($types as $type) {
            switch ($type) {
                case 'region':
                    $data = array_merge($this->searchRegion($query), $data);
                break;
                case 'departement':
                    $data = array_merge($this->searchDepartement($query), $data);
                break;
                case 'ville':
                    $data = array_merge($this->searchVille($query), $data);
                break;
                case 'products':
                    $data = array_merge($this->searchProduct($query), $data);
                break;
                case 'user':
                    $data = array_merge($this->searchUser($query), $data);
                break;
            }
        }

        if ($json) {
            FB('Search to jSon');
            $data = $this->MySearchToJson($query, $data);
        }

        if (self::cached && $json) {
            FB('Saving file cache');
            $this->_cache = json_decode($data);
            $this->saveCache($this->_cache, $file_cache);
        }

        FB('return data');
        return $data;
    }


    private function saveCache($data, $file)
    {
        $data = json_encode($data);
        $fp = fopen ($file, "w+");
        fseek ($fp, 0);
        fputs ($fp, $data);
        fclose ($fp);
    }


    /**
     * Effectue une recherche dans les fichiers JSON
     *
     * @param string $query La valeur actuelle du champ
     * @param mixed $data Toutes les occurences contenant la valeur du champ
     * @return string La chaîne encodée au format JSON
     */
    private function MySearchToJson($query, $data)
    {
        $string = array();
        $string['query'] = $query;

        foreach ($data as $value => $response) {
            $string['suggestions'][] = $value;
            $string['data'][] = json_encode($response);
        }

        return json_encode($string);
    }

    /**
     * Recherche une ville
     *
     * @param string $query La valeur actuelle du champ
     * @return mixed $data Toutes les occurences contenant la valeur du champ
     */
    private function searchVille($query)
    {
        $list = Base::Load(CLASS_LOC)->getVille();
        $data = array();
        $queryLower = Tools::toLevel($query);
        foreach ($list as $ville) {
            $attr = $ville[2];
            if (preg_match('/'.$queryLower.'/', Tools::toLevel($attr))) {
                $data[$attr]['id'] = $ville[0];
                $data[$attr]['type'] = 'ville';
            }
        }

        return $data;
    }

    /**
     * Recherche un département
     *
     * @param string $query La valeur actuelle du champ
     * @return mixed $data Toutes les occurences contenant la valeur du champ
     */
    private function searchDepartement($query)
    {
        $list = Base::Load(CLASS_LOC)->getDepartement();
        $data = array();
        $queryLower = Tools::toLevel($query);

        foreach ($list as $departement) {
            foreach ($departement as $attr) {
                if (preg_match('/'.$queryLower.'/', Tools::toLevel($attr))) {
                    $data[$attr]['id'] = $departement[2];
                    $data[$attr]['type'] = 'departement';
                }
            }
        }

        return $data;
    }

    /**
     * Recherche un produit
     *
     * @param string $query La valeur actuelle du champ
     * @return mixed $data Toutes les occurences contenant la valeur du champ
     */
    private function searchProduct($query)
    {
        $list = Base::Load(CLASS_PRODUCT)->getAll();
        $data = array();
        $queryLower = Tools::toLevel($query);

        foreach ($list as $i=> $element) {
            if (preg_match('/'.$queryLower.'/', Tools::toLevel($element['name']))) {
                $data[$element['name']]['id'] = $i;
                $data[$element['name']]['type'] = 'reports';
            }
        }
        return $data;
    }

    /**
     * Recherche une région
     *
     * @param string $query La valeur actuelle du champ
     * @return mixed $data Toutes les occurences contenant la valeur du champ
     */
    private function searchRegion($query)
    {
        $list = Base::Load(CLASS_LOC)->getRegion();
        $data = array();
        $queryLower = Tools::toLevel($query);
        
        foreach ($list as $region) {
            foreach ($region as $attr) {
                if (preg_match('/'.$queryLower.'/', Tools::toLevel($attr))) {
                    $data[$attr]['id'] = $region[0];
                    $data[$attr]['type'] = 'region';
                }
            }
        }
        
        return $data;
    }


    /**
     * Recherche un user
     *
     * @param string $query La valeur actuelle du champ
     * @return mixed $data Toutes les occurences contenant la valeur du champ
     */
    private function searchUser($query)
    {
        $list = Base::Load(CLASS_USER)->getAll();
        $data = array();
        $queryLower = Tools::toLevel($query);

        foreach ($list as $elem) {
            if (preg_match('/'.$queryLower.'/', Tools::toLevel($elem['nom']))) {
                $data[$elem['nom'].' '.$elem['prenom']]['id'] = (string)$elem['_id'];
                $data[$elem['nom'].' '.$elem['prenom']]['type'] = 'hunters';
            }
        }
        foreach ($list as $elem) {
            if (preg_match('/'.$queryLower.'/', Tools::toLevel($elem['prenom']))) {
                $data[$elem['nom'].' '.$elem['prenom']]['id'] = (string)$elem['_id'];
                $data[$elem['nom'].' '.$elem['prenom']]['type'] = 'hunters';
            }
        }
        return $data;
    }
}


/* -- Fin du fichier -- */